/*
    This file is part of QTau
    Copyright (C) 2013-2018  Tobias "Tomoko" Platen <tplaten@posteo.de>
    Copyright (C) 2013       digited       <https://github.com/digited>
    Copyright (C) 2010-2013  HAL@ShurabaP  <https://github.com/haruneko>

    QTau is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    SPDX-License-Identifier: GPL-3.0+
*/

#define __devloglevel__ 5
#include "audio/audioengine.h"
#include "audio/jackaudio.h"
#include "PluginInterfaces.h"

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include "../Controller.h"

AudioEngine::AudioEngine(JackAudio* jack,QObject *parent) :
    QThread(parent)
{
    _jack = jack;
    _jack_buffer = _jack->allocateBuffer();
    _jack_buffer_size = _jack->getBufferSize();
    _eventfd = _jack->createEFD();
    _pos=0;
    start();
}

void AudioEngine::shutdown()
{
    _running = false;
    uint64_t u=2;
    int ret = write(_eventfd, &u, sizeof(uint64_t));
    if(ret==8) usleep(100);
}

void AudioEngine::run()
{
    while(_running)
    {
        uint64_t u;
        int count = read(_eventfd, &u, sizeof(uint64_t));
        if(u==1 && count==8)
        {
            memset(_jack_buffer,0,_jack_buffer_size*sizeof(float));

            bool isRolling;
            if(_useJackTransport) isRolling=_jack->isRolling();
            else isRolling=_localTransportRolling;

            if(isRolling)
            {

                //if(_scheduledSynth) {
                //    _scheduledSynth->readData(_jack_buffer,_jack_buffer_size);
                //}
                _outp->readData(_jack_buffer,_jack_buffer_size);

                _pos += _jack_buffer_size;
                if(_useJackTransport) _lastJackTransportPos = _pos;


            }

            if(_preview) _preview->readData(_jack_buffer,_jack_buffer_size);

            _jack->writeData(_jack_buffer,_jack_buffer_size*sizeof(float));

        }
    }
}
